﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Resources;
using Cesave.Domain.Core;
using System.Data;

namespace Cesave.Domain.PermisosModule.Contracts.FoliosPermisos
{
	public class FoliosPermisoService
		: IFoliosPermisoService
	{
		#region Private properties

		private IFoliosPermisoRepository _foliosPermisoRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="foliosPermisoRepository"></param>
		public FoliosPermisoService(IFoliosPermisoRepository foliosPermisoRepository)
		{
			if (foliosPermisoRepository == null)
				throw new ArgumentNullException(Messages.exception_DependenciesAreNotInitialized, "foliosPermisoRepository");
			_foliosPermisoRepository = foliosPermisoRepository;
		}

		#endregion

		#region IFoliosPermisoService Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="folio"></param>
		public void AddFoliosPermiso(Entities.FoliosPermiso folio)
		{
			if (folio == null)
				throw new ArgumentNullException(Messages.exception_InvalidArgument, "folio");
			IUnitOfWork unitOfWork = _foliosPermisoRepository.StoreContext;
			_foliosPermisoRepository.Add(folio);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="folio"></param>
		public void ChangeFoliosPermiso(Entities.FoliosPermiso folio)
		{
			if (folio == null)
				throw new ArgumentNullException(Messages.exception_InvalidArgument, "folio");
			IUnitOfWork unitOfWork = _foliosPermisoRepository.StoreContext;
			_foliosPermisoRepository.Modify(folio);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <param name="areaGuid"></param>
		/// <returns></returns>
		public int IncreaseFoliosPermiso(Guid juntaGuid, Guid cicloGuid, Guid areaGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			if (areaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "areaGuid");
			var specification = new FoliosPermisoByJuntaAndCicloAndAreaSpecification(juntaGuid, cicloGuid, areaGuid);
			var folio = _foliosPermisoRepository.FindFoliosPermisoByJuntaAndCicloAndArea(specification);
			folio.Folio = folio.Folio + 1;
			IUnitOfWork unitOfWork = _foliosPermisoRepository.StoreContext;
			_foliosPermisoRepository.Modify(folio);
			try
			{
				unitOfWork.Commit();
				return folio.SiguienteFolio;
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
				return 0;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <param name="areaGuid"></param>
		/// <returns></returns>
		public Entities.FoliosPermiso FindFolioPermisoByJuntaAndCicloAndArea(Guid juntaGuid, Guid cicloGuid, Guid areaGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			if (areaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "areaGuid");
			var specification = new FoliosPermisoByJuntaAndCicloAndAreaSpecification(juntaGuid, cicloGuid, areaGuid);
			var folio = _foliosPermisoRepository.FindFoliosPermisoByJuntaAndCicloAndArea(specification);
			if (folio == null)
			{
				folio = new Entities.FoliosPermiso
				{
					FolioGuid = Guid.NewGuid(),
					AreaGuid = areaGuid,
					CicloGuid = cicloGuid,
					Folio = 0,
					JuntaGuid = juntaGuid,
				};
				IUnitOfWork unitOfWork = _foliosPermisoRepository.StoreContext;
				_foliosPermisoRepository.Add(folio);
				try
				{
					unitOfWork.Commit();
				}
				catch (OptimisticConcurrencyException)
				{
					unitOfWork.RollbackChanges();
					unitOfWork.CommitAndRefreshChanges();
				}
			}
			return folio;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <returns></returns>
		public List<Entities.FoliosPermiso> FindFoliosPermisoByJuntaAndCiclo(Guid juntaGuid, Guid cicloGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			var specification = new FoliosPermisosByJuntaAndCicloSpecification(juntaGuid, cicloGuid);
			return _foliosPermisoRepository.FindFoliosPermisoByJuntaAndCiclo(specification).OrderBy(f => f.Folio).ToList();
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_foliosPermisoRepository != null && _foliosPermisoRepository.StoreContext != null)
				_foliosPermisoRepository.StoreContext.Dispose();
		}

		#endregion
	}
}
